package com.samnative.pineapple.http;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.util.Log;

import com.blankj.utilcode.util.LogUtils;
import com.samnative.pineapple.instance.AppPrefer;
import com.shashank.sony.fancytoastlib.FancyToast;
import com.samnative.pineapple.main.R;
import com.samnative.pineapple.utils.MD5Util;
import com.samnative.pineapple.value.Config;
import com.samnative.pineapple.widget.LoadingDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2019/5/13.
 * <p>
 * HTTP请求类
 */

public class HttpRequest {

    /**
     * 客户端对象
     */
    public static OkHttpClient okHttpClient = new OkHttpClient();


    /**
     * post请求,Actitivy专用
     *
     * @param activity
     * @param lodingstr
     * @param map
     */
    public static void post(Activity activity, String lodingstr, Map<String, String> map, JsonResult result) {
        Request request = new Request.Builder()
                .url(Config._API_URL)
                .post(addParameter(map))
                .build();
        Call call = okHttpClient.newCall(request);
        if (lodingstr != null) {
            LoadingDialog.getInstance(activity).setMessage(lodingstr).show();
        }
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //连接失败

                        FancyToast.showToast(activity, activity.getString(R.string.no_network), FancyToast.WARNING, false);
                        if (lodingstr != null) {
                            LoadingDialog.dismissDialog();
                        }
                        result.requestFailure(0, "");
                        result.requestFinish();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(str);
                    int code = jsonObject.optInt("code");
                    String msg = jsonObject.optString("msg");
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            if (code == 200) {
                                //请求成功,返回JSON
                                result.reqestSuccess(jsonObject);
                            } else {
                                //请求发生错误
                                result.requestFailure(code, msg);
                                FancyToast.showToast(activity, msg, FancyToast.WARNING, false);
                            }
                            result.requestFinish();
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            result.requestFailure(0, "");
                            result.requestFinish();
                        }
                    });
                }

                //打印返回结果
                int segmentSize = 3 * 1024;
                long length = str.length();
                if (length <= segmentSize) {// 长度小于等于限制直接打印
                    LogUtils.e(str);
                } else {
                    while (str.length() > segmentSize) {// 循环分段打印日志
                        String logContent = str.substring(0, segmentSize);
                        str = str.replace(logContent, "");
                        LogUtils.e(logContent);
                    }
                    LogUtils.e(str);// 打印剩余日志
                }
            }


        });
    }


    /**
     * post请求,非Activity使用,静默使用无提示
     * <p>
     * 结果在线程中返回
     *
     * @param map
     */
    public static void post(Map<String, String> map, JsonResult result) {
        Request request = new Request.Builder()
                .url(Config._API_URL)
                .post(addParameter(map))
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //连接失败
                result.requestFailure(0, "");
                result.requestFinish();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(str);
                    int code = jsonObject.optInt("code");
                    String msg = jsonObject.optString("msg");
                    if (code == 200) {
                        //请求成功,返回JSON
                        result.reqestSuccess(jsonObject);
                    } else {
                        //请求发生错误
                        result.requestFailure(code, msg);
                    }
                    result.requestFinish();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                LogUtils.e(str);
            }


        });
    }

    /**
     * 生成签名
     * <p>
     * 所有请求参数 按键值排序，然后用'&'拼接，尾部 不带'&' ，后面加上私钥一起md5
     *
     * @param p_Map 原始业参
     * @return
     */
    public static String getSign(Map<String, String> p_Map) {
        List<String> m_SNList = new ArrayList<String>();
        // 1,所有业参链起来
        if (p_Map != null) {
            for (Map.Entry<String, String> entry : p_Map.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                m_SNList.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        // 2,按照key排序
        Collections.sort(m_SNList);
//        // 3,去掉所有key只保留value
//        for (int i = 0; i < m_SNList.size(); i++) {
//            String temp = m_SNList.get(i);
//            LogUtils.showLog(temp);
//            int index = temp.indexOf(":");
//            if (index != -1) {
//                temp = temp.substring(index + 1, temp.length());
//            }
//            m_SNList.set(i, temp);
//        }
        // 4,转换为字符串
        String m_StrAsc = "";
        for (String item : m_SNList) {
            m_StrAsc += item;
        }

        if (m_StrAsc.length() > 0) {
            m_StrAsc = m_StrAsc.substring(0, m_StrAsc.length() - 1);
        }
//        LogUtils.showLog("MD5之前=" + m_StrAsc + _nnh_key);
        // MD5序列
        return MD5Util.getMD5Str(m_StrAsc + Config._API_KEY);
    }


    /**
     * 封装请求参数
     *
     * @return 封装完成参数
     */
    public static RequestBody addParameter(Map<String, String> map) {
        // 应用级参数
        String cc = System.currentTimeMillis() + ""
                + (new Random().nextInt(9000) + 1000);
        String method = map.get("_apiname");
        if (method == null) {
            method = "";
        }
        String temp = MD5Util.getMD5Str(cc + Config._API_KEY)
                + MD5Util.getMD5Str(cc + Config._API_KEY + method);
        int index = Integer
                .parseInt(cc.substring(cc.length() - 1, cc.length()));
        String ck = temp.substring(index, index + 51);
        map.put("_cc", cc);
        map.put("_ck", ck);
        // 系统级参数
        map.put("_devid", Config._API_DEV);
        map.put("_env", getInfo());
        map.put("_time", System.currentTimeMillis() + "");
        map.put("_network", Config._network);
        map.put("checktoken", getSign(map));

        StringBuilder sbLog = new StringBuilder();
        FormBody.Builder builder = new FormBody.Builder();
        if (map != null) {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                builder.add(entry.getKey(), entry.getValue());
                sbLog.append(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }

        String log = sbLog.toString();
        if (log.length() > 0) {
            log = log.substring(0, sbLog.length() - 1);
        }
        LogUtils.e(Config._API_URL + "?" + log);
        return builder.build();
    }

    /**
     * 返回设备信息
     *
     * @return
     */
    public static String getInfo() {
        String info = "";
        JSONObject json = new JSONObject();
        try {
            json.put("_v", "A" + Config._API_VERSION);
            json.put("uu", Config._uuid);
            json.put("model", Build.BRAND + "_" + Build.MODEL);
            json.put("dpi", Config._dpi);
            json.put("systemver", "Android_" + Build.VERSION.RELEASE);
            json.put("deviceid", Build.DEVICE);
            json.put("longitude", Config.longitude);
            json.put("latitude", Config.latitude);
            info = json.toString();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return info;
    }


    //=======================================================================================新项目用的

    /**
     * post请求,Actitivy专用
     *
     * @param activity
     * @param lodingstr
     * @param params
     */
    public static void request(Activity activity, String routeUrl, String lodingstr, Object params, String requestType, JsonResult result) {
        Request request = null;

        switch (requestType) {
            case "POST":
            case "post":
                request = new Request.Builder()
                        .url(Config._API_URL + routeUrl)
                        .post(getBodyParams(params))
                        .headers(getHeaherParams(activity))
                        .build();
                break;
            case "GET":
            case "get":
                request = new Request.Builder()
                        .url(Config._API_URL + routeUrl + getQueryParams(params))
                        .get()
                        .headers(getHeaherParams(activity))
                        .build();
                break;
        }

        LogUtils.e("当前请求=" + request.url());

        Call call = okHttpClient.newCall(request);
        if (lodingstr != null) {
            LoadingDialog.getInstance(activity).setMessage(lodingstr).show();
        }
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //连接失败
                        FancyToast.showToast(activity, activity.getString(R.string.no_network), FancyToast.WARNING, false);
                        if (lodingstr != null) {
                            LoadingDialog.dismissDialog();
                        }
                        result.requestFailure(0, "");
                        result.requestFinish();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(str);
                    int code = jsonObject.optInt("code");
                    String msg = jsonObject.optString("msg");
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            if (code == 200) {
                                //请求成功,返回JSON
                                result.reqestSuccess(jsonObject);
                            } else {
                                //请求发生错误
                                result.requestFailure(code, msg);
                                FancyToast.showToast(activity, msg, FancyToast.WARNING, false);
                            }
                            result.requestFinish();
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            result.requestFailure(0, "");
                            result.requestFinish();
                        }
                    });
                }
                //打印返回结果
                int segmentSize = 3 * 1024;
                long length = str.length();
                if (length <= segmentSize) {// 长度小于等于限制直接打印
                    LogUtils.e(str);
                } else {
                    while (str.length() > segmentSize) {// 循环分段打印日志
                        String logContent = str.substring(0, segmentSize);
                        str = str.replace(logContent, "");
                        LogUtils.e(logContent);
                    }
                    LogUtils.e(str);// 打印剩余日志
                }
            }


        });
    }


    /**
     * post请求,非Activity使用,静默使用无提示
     * <p>
     * 结果在线程中返回
     *
     * @param params
     */
    public static void request(Context context, String routeUrl, Object params, String requestType, JsonResult result) {
        Request request = null;

        switch (requestType) {
            case "POST":
            case "post":
                request = new Request.Builder()
                        .url(Config._API_URL + routeUrl)
                        .post(getBodyParams(params))
                        .headers(getHeaherParams(context))
                        .build();
                break;
            case "GET":
            case "get":
                request = new Request.Builder()
                        .url(Config._API_URL + routeUrl + getQueryParams(params))
                        .get()
                        .headers(getHeaherParams(context))
                        .build();
                break;
        }

        LogUtils.e("当前请求=" + request.url());

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //连接失败
                result.requestFailure(0, "");
                result.requestFinish();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(str);
                    int code = jsonObject.optInt("code");
                    String msg = jsonObject.optString("msg");
                    if (code == 200) {
                        //请求成功,返回JSON
                        result.reqestSuccess(jsonObject);
                    } else {
                        //请求发生错误
                        result.requestFailure(code, msg);
                    }
                    result.requestFinish();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                LogUtils.e(str);
            }


        });
    }

    /**
     * 封装参数到POST请求
     * 需要判断传入的是map参数，还是JSON字符串
     * 支持两种参数形式
     */
    public static RequestBody getBodyParams(Object params) {
        MediaType JSON = MediaType.get("application/json; charset=utf-8");
        JSONObject json = new JSONObject();
        if (params instanceof String) {
            //JSON字符串参数，不用转换,直接提交
            LogUtils.e("提交参数=" + String.valueOf(params));
            return RequestBody.create(JSON, String.valueOf(params));
        } else {
            //不是字符串，那就转成map然后封装
            Map<String, String> map = (Map<String, String>) params;
            if (map != null && map.size() > 0) {
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    if (entry.getValue() == null) {
                        continue;
                    }
                    try {
                        json.put(entry.getKey(), entry.getValue());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
            LogUtils.e("提交参数=" + String.valueOf(json));
            return RequestBody.create(JSON, String.valueOf(json));
        }
    }


    /**
     * 封装参数到Get请求
     *
     * @param params
     * @return
     */
    private static String getQueryParams(Object params) {

        Map<String, String> queryParams = (Map<String, String>) params;
        if (queryParams != null && queryParams.size() > 0) {
            StringBuffer sb = new StringBuffer("?");
            for (String key : queryParams.keySet()) {
                if (queryParams.get(key) != null) {
                    sb.append("&");
                    sb.append(key);
                    sb.append("=");
                    sb.append(queryParams.get(key));
                }
            }
            return sb.toString();
        } else {
            return "";
        }
    }

    /**
     * 封装参数到head中
     * <p>
     * 一般都是非业务参数，这里需要的事传入用户token
     *
     * @return
     */
    private static Headers getHeaherParams(Context context) {
        Headers headers = null;
        Headers.Builder headersBuilder = new Headers.Builder();
        String mtoken = AppPrefer.getInstance(context).getString(AppPrefer.mtoken, "");
        if (!mtoken.equals("")) {
            headersBuilder.add("token", mtoken);
        }
        headers = headersBuilder.build();
        return headers;
    }


    /**
     * 上传图片到服务器
     */
    public static void postImage(Activity activity, String routeUrl, String lodingstr, String imgpath, JsonResult result) {

        File mFile = new File(imgpath);
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), mFile);

        MultipartBody multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", mFile.getName(), requestBody)
                .build();

        Request request = new Request.Builder()
                .url(Config._API_URL + routeUrl)
                .post(multipartBody)
                .headers(getHeaherParams(activity))
                .build();

        LogUtils.e("当前请求=" + request.url());

        Call call = okHttpClient.newCall(request);
        if (lodingstr != null) {
            LoadingDialog.getInstance(activity).setMessage(lodingstr).show();
        }
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //连接失败
                        FancyToast.showToast(activity, activity.getString(R.string.no_network), FancyToast.WARNING, false);
                        if (lodingstr != null) {
                            LoadingDialog.dismissDialog();
                        }
                        result.requestFailure(0, "");
                        result.requestFinish();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();

                try {
                    JSONObject jsonObject = new JSONObject(str);
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            if (jsonObject.has("url")) {
                                //请求成功,返回JSON
                                result.reqestSuccess(jsonObject);
                            } else {
                                //请求发生错误
                                result.requestFailure(0, "");
                                FancyToast.showToast(activity, "上传失败", FancyToast.WARNING, false);
                            }
                            result.requestFinish();
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (lodingstr != null) {
                                LoadingDialog.dismissDialog();
                            }
                            result.requestFailure(0, "");
                            result.requestFinish();
                        }
                    });
                }
                //打印返回结果
                int segmentSize = 3 * 1024;
                long length = str.length();
                if (length <= segmentSize) {// 长度小于等于限制直接打印
                    LogUtils.e(str);
                } else {
                    while (str.length() > segmentSize) {// 循环分段打印日志
                        String logContent = str.substring(0, segmentSize);
                        str = str.replace(logContent, "");
                        LogUtils.e(logContent);
                    }
                    LogUtils.e(str);// 打印剩余日志
                }
            }


        });
    }
}
